const axios = require('axios');
const url = require('url');
const cookie = require('cookie');
const util = require('util');
const Tool = require('./../util/tool.js');
const log = require('./../util/log.js');

const cookieNames = ['did', 'didv', '_did'];

function parse(inputUrl, req, res, conf) {
    const options = {
        inputUrl: inputUrl,
        userAgent: Tool.randomEle(conf.phoneUA),
    }
    axios.get(inputUrl, {
        headers: {
            'User-Agent': options.userAgent,
        }
    }).then((response) => {
        // log.log('response 数据: ', response);
        let cookies = [];
        let redirectUrl = response.request.res?.responseUrl;
        response.headers['set-cookie'].forEach(header => {
            let info = cookie.parse(header);
            Object.getOwnPropertyNames(info)
                .filter(key => cookieNames.includes(key))
                .forEach(key => cookies.push(key + "=" + info[key]));
        });
        const opts = {
            targetUrl: redirectUrl || inputUrl,
            cookies: cookies,
        }
        Object.assign(options, opts);
        log.info("options: ", options);
        getVideoInfo(options, req, res, conf);
    }).catch((error) => {
        let data = {
            status: 1,
            errMsg: "解析失败"
        };
        res.json(data);
        log.error(data);
        log.error('error 数据: ', error);
    }).finally(() => { });
}


function getVideoInfo(options, req, res, conf) {
    const parsedUrl = url.parse(options.targetUrl, true); // 第二个参数为true，则解析查询字符串
    // log.log("parsedUrl: ", parsedUrl)
    let param = parsedUrl.query;
    let opts = {
        "fid": param.fid,
        "shareToken": param.shareToken,
        "shareObjectId": param.shareObjectId || param.originShareId,
        "shareMethod": param.shareMethod,
        "shareId": param.shareId,
        "shareResourceType": param.shareResourceType,
        "shareChannel": param.cc,
        "kpn": param.kpn,
        "subBiz": param.subBiz,
        "env": "SHARE_VIEWER_ENV_TX_TRICK",
        "h5Domain": parsedUrl.hostname,
        "photoId": param.photoId,
        "isLongVideo": false
    };
    log.info("opts: ", opts);
    axios({
        method: "post",
        url: "https://v.m.chenzhongtech.com/rest/wd/photo/info?kpn=KUAISHOU&captchaToken=&__NS_sig3=9989cdfe9bd0ddaca3c4c7c69b1a89778ec4c9b8d8d8dadad5d4d7cd",
        headers: {
            "Referer": options.targetUrl,
            "User-Agent": options.userAgent,
            "Cookie": options.cookies.join("; "),
        },
        data: opts,
    }).then((response) => {
        let data = response.data;
        // log.log('响应数据 response: ', response);
        // log.log('响应数据 headers: ', response.headers);
        // log.log('响应数据 data: ', data);
        if (data.result == 1) {
            // 主要信息提取
            let result = formatResult(data, conf)
            log.info('最终解析数据 : ', result);
            res.json({
                status: 0,
                data: result
            });
        } else {
            console.info("data ::", data);
            throw new Error("读取数据丢失", data);
        }
    });
}



function formatResult(data, conf) {
    let mainUrls;
    let photo = data.photo;
    let info = {
        desc: photo.caption,
        photoId: photo.photoId,
        share_info: photo.share_info
    }
    let user = {
        userName: photo.userName,
        userId: photo.userId,
        userSex: photo.userSex,
        headUrl: photo.headUrl,
        userEid: photo.userEid
    }
    let type = conf.resultType[photo.photoType];
    let typeCode = photo.ext_params.mtype;
    switch (type) {
        case "video": // VIDEO photo.ext_params.mtype = 3 视频
            mainUrls = [photo.mainMvUrls?.[0]?.url];
            console.info("soundTrack :: ", photo.soundTrack);
            Object.assign(info, {
                videoUrls: photo.mainMvUrls?.map(x => x.url) || [],
                coverUrls: photo.coverUrls?.map(x => x.url) || [],
                musicUrls: photo.soundTrack?.audioUrls?.map(x => x.url) || []
            });
            break;
        case "atlas": // HORIZONTAL_ATLAS photo.ext_params.mtype = 6 图集
            let atlas = photo.ext_params.atlas;
            // let musicUrls = intersectUrls(atlas.music, [...atlas.musicCdnList.map(x => x.cdn), ...atlas.cdnList.map(x => x.cdn)], "https://%s%s", true);
            let musicUrls = intersectUrls(atlas.music, atlas.musicCdnList.map(x => x.cdn), "https://%s%s", true);
            let photoUrls = intersectUrls(atlas.list, atlas.cdn, "https://%s%s", true);
            mainUrls = photoUrls?.map(x => x?.[0]) || [];
            Object.assign(info, {
                photoUrls: photoUrls,
                musicUrls: musicUrls,
            });
            break;
        default:
            mainUrls = [];
            info = photo;
            break;
    }
    let result = {
        type: type,
        typeCode: typeCode,
        mainUrls: mainUrls,
        info: info,
        user: user
    }
    return result;
}

function crossUrls(arg1, arg2, format = "http://%s%s", cross = false) {
    let cdns = arg1, paths = arg2;
    if (typeof (arg1) == "string") {
        cdns = [arg1];
    } else if (!Array.isArray(arg1)) {
        return [];
    }
    if (typeof (arg2) == "string") {
        paths = [arg2];
    } else if (!Array.isArray(arg2)) {
        return [];
    }
    let result = []
    for (let i = 0; i < cdns.length; i++) {
        result[i] = [];
        for (let j = 0; j < paths.length; j++) {
            let sorts = cross ? [paths[j], cdns[i]] : [cdns[i], paths[j]];
            result[i][j] = {
                cdn: sorts[0],
                url: util.format(format, ...sorts)
            }
        }
    }
    return result;
}

function intersectUrls(arg1, arg2, format = "http://%s%s", cross = false) {
    let cdns = arg1, paths = arg2;
    if (typeof (arg1) == "string") {
        cdns = [arg1];
    } else if (!Array.isArray(arg1)) {
        return [];
    }
    if (typeof (arg2) == "string") {
        paths = [arg2];
    } else if (!Array.isArray(arg2)) {
        return [];
    }
    let result = []
    for (let i = 0; i < cdns.length; i++) {
        result[i] = [];
        for (let j = 0; j < paths.length; j++) {
            let sorts = cross ? [paths[j], cdns[i]] : [cdns[i], paths[j]];
            result[i].push(util.format(format, ...sorts));
        }
    }
    if (result.length == 1) {
        return result[0];
    }
    return result;
}

module.exports = { parse };